<!DOCTYPE html>
<html>
<head>
<title>Right Angle Task</title>
<!-- stylesheets -->
<link rel="stylesheet" type="text/css" href="../core/core.css">
<!-- JS -->
<script src="../core/core.js"></script>
<script src="../core/d3.v3.min.js"></script>
<script src="../common/shapes.js"></script>

<style>
#area { position: relative; height: 160px; width: 160px; }
#area svg { width: 150px; height: 130px; }
#subbtn { left: 30px; bottom: 5px; position: absolute; }
</style>

<script>
var RADIUS_PADDING = 3; // 3px for circle radius
var QUERY_PADDING = 50; // 50px for #query height

function graphClicked(event) {
  var x = event.pageX;
  var y = event.pageY;

  var divWidth = document.getElementById('svg-grid').clientWidth;
  var divHeight = document.getElementById('svg-grid').clientHeight;

  var svg = d3.select('svg');

  d3.selectAll('.blue').remove();

  shapes.drawCircles([{ class: 'blue', id: 'blue-circle', cx: x, cy: (y-QUERY_PADDING), r:3,
    fill: 'blue' }], svg);

  var blueCircle = d3.select('#blue-circle')[0][0].getBBox();
  var initCircle = d3.selectAll('#init-blue')[0][0].getBBox();

  shapes.drawLines([{ stroke: 'blue', class: 'blue', x1: (blueCircle.x + RADIUS_PADDING),
    x2: (initCircle.x + RADIUS_PADDING), y1: (blueCircle.y + RADIUS_PADDING),
    y2: (initCircle.y + RADIUS_PADDING) }], svg);
}

// instead of drawing a single, random, valid point on the grid,
// it's probably easier to generate a line denoting all acceptable
// points on the grid.
var drawAnswers = function(pointA, pointB){
  var svg = d3.select('svg');

  shapes.drawCircles([
    { class: 'green', id: 'pointA', cx: (pointA.x + RADIUS_PADDING),
      cy: (pointA.y + RADIUS_PADDING), r: 3, fill: 'green' },
    { class: 'green', id: 'pointB', cx: (pointB.x + RADIUS_PADDING),
      cy: (pointB.y + RADIUS_PADDING), r: 3, fill: 'green' }
    ], svg);

  shapes.drawLines([{ stroke: 'green', class: 'green', x1: (pointA.x + RADIUS_PADDING),
    x2: (pointB.x + RADIUS_PADDING), y1: (pointA.y + RADIUS_PADDING), y2: (pointB.y + RADIUS_PADDING)
    }], svg);
}

var computeDistances = function(){
  var pointA = d3.select('#init-black')[0][0].getBBox();
  var pointVertex = d3.select('#init-blue')[0][0].getBBox();
  var correctPoint = showPerpendicular(pointA, pointVertex);

  // error handle for submitting without any shapes
  if(d3.select('#blue-circle')[0][0] === null) {
    core.endEpisode(-1, false);
    return;
  }
  var pointB = d3.select('#blue-circle')[0][0].getBBox();
  var userAngle = findAngle(pointA,pointB, pointVertex);
  var expectedAngle = 90;
  var diff = Math.abs(expectedAngle-userAngle);

  if(diff < 45) core.endEpisode((expectedAngle-diff)/expectedAngle, true);
  else core.endEpisode(-1.0, false);
}

// given pointA, pointB and the vertex that is joined to both of these points,
// return the angle made by all three points.
var findAngle = function(pointA,pointB, pointVertex) {
  var pAV = Math.sqrt(Math.pow(pointVertex.x-pointA.x,2) + Math.pow(pointVertex.y-pointA.y,2));
  var pBV = Math.sqrt(Math.pow(pointVertex.x-pointB.x,2) + Math.pow(pointVertex.y-pointB.y,2));
  var pApB = Math.sqrt(Math.pow(pointB.x-pointA.x,2) + Math.pow(pointB.y-pointA.y,2));
  var radAngle = Math.acos((pBV*pBV+pAV*pAV-pApB*pApB)/(2*pBV*pAV));
  return (radAngle*180)/ Math.PI; // return in degrees
}

// find two perpendicular points to create the line denoting
// where the correct answer lies, then draw the answer.
var showPerpendicular = function(pointA, pointVertex){
  var slope = (pointVertex.y - pointA.y) / (pointVertex.x - pointA.x);
  var inverseSlope = -1/slope;

  var yAxis = pointVertex.y - inverseSlope*pointVertex.x; //  y=mx+b => b=y-mx

  var perpendicularPointA = {};
  perpendicularPointA.x = (-10 - yAxis)/inverseSlope; // y=mx+b => (y-b)/m = x
  perpendicularPointA.y = -10;

  var perpendicularPointB = {};
  perpendicularPointB.x = (140 - yAxis)/inverseSlope;
  perpendicularPointB.y = 140;

  drawAnswers(perpendicularPointA, perpendicularPointB);
}

var generateCircles = function(){
  var jsonCircles = []
  jsonCircles.push({ cx: core.randi(5,135), cy: core.randi(10, 120), fill: 'black', id: 'init-black',
    r: 3.5, class: 'black-circle' });

  while(jsonCircles.length === 1){
    var newCircle = { cx: core.randi(5, 135), cy: core.randi(10,125), fill: 'blue', id: 'init-blue',
      r: 3.5, class: 'black-circle'}

    var xDiff = Math.abs(newCircle.cx - jsonCircles[0].cx);
    var yDiff = Math.abs(newCircle.cy - jsonCircles[0].cy);
    if(xDiff < 30 && yDiff < 30) continue;
    else jsonCircles.push(newCircle);
  }

  return jsonCircles;
}

var setupProblem = function(svg){
  jsonCircles = generateCircles();

  shapes.drawCircles(jsonCircles, svg);
  shapes.drawLines([{ x1: jsonCircles[0].cx, x2: jsonCircles[1].cx, y1: jsonCircles[0].cy,
    y2: jsonCircles[1].cy }], svg);
}

var genProblem = function() {
  var svg = d3.select('svg');
  svg.selectAll('*').remove();

  setupProblem(svg);
  svg.on('click', function(){ graphClicked(event); });

  d3.select('#subbtn').on('click', function(){
    computeDistances();
  });
}

window.onload = function() {
  core.startEpisode();
}
</script>
</head>
<body>
<div id="wrap">
  <div id="query">Add a third point to create a right angle, then press submit.</div>
  <div id="area">
    <svg id="svg-grid"></svg>
    <button id="subbtn" class="secondary-action">Submit</button>
  </div>
</div>
</body>
</html>
